﻿''' <summary>
''' Provides functionality for managing song categories in a PowerSong database.
''' </summary>
Public Class Categories

    Friend FDatabase As Database = Nothing
    Friend FCategoriesData As Data.CategoriesDataTable = Nothing

    Friend Sub New(ByVal database As Database)

        FDatabase = database
        FCategoriesData = database.Data.Categories

    End Sub

    ''' <summary>
    ''' Gets all categories contained in the active database.
    ''' </summary>
    ''' <returns>A list of all of the category IDs and Names in the active database.</returns>
    Public Function GetAllCategories() As Dictionary(Of Guid, String)

        Dim Result As New Dictionary(Of Guid, String)
        For Each Category As Data.CategoriesRow In FCategoriesData
            Result.Add(Category.CategoryID, Category.Name)
        Next
        Return Result

    End Function

    ''' <summary>
    ''' Determines whether or not the given category name exists.
    ''' </summary>
    ''' <param name="categoryName">The name of the category to search for.</param>
    ''' <returns>True, if the category exists. False otherwise.</returns>
    Public Function CategoryExists(ByVal categoryName As String) As Boolean

        For Each Category As Data.CategoriesRow In FCategoriesData
            If Category.Name.ToUpper = categoryName.ToUpper Then Return True
        Next
        Return False

    End Function

    ''' <summary>
    ''' Gets the name of the category, given its ID.
    ''' </summary>
    ''' <param name="categoryID">The ID of the category whose name to retrieve.</param>
    ''' <returns>The name of the category, based on the given ID.</returns>
    Public Function GetCategoryName(ByVal categoryID As Guid) As String
        Return FCategoriesData.FindByCategoryID(categoryID).Name
    End Function

    ''' <summary>
    ''' Gets the category ID, based on its name.
    ''' </summary>
    ''' <param name="categoryName">The name of the category whose ID to retrieve.</param>
    ''' <returns>The ID of the category with the given name.</returns>
    Public Function GetCategoryID(ByVal categoryName As String) As Guid

        ' Try to find the category
        For Each Row As Data.CategoriesRow In FCategoriesData
            If Row.Name.ToUpper = categoryName.ToUpper Then Return Row.CategoryID
        Next

        ' The category could not be found
        Throw New ApplicationException("The category '" + categoryName + "' could not be found.")

    End Function

    ''' <summary>
    ''' Changes the name of a category.
    ''' </summary>
    ''' <param name="categoryID">The category ID whose name to change.</param>
    ''' <param name="newName">The new name of the category.</param>
    Public Sub ChangeCategoryName(ByVal categoryID As Guid, ByVal newName As String)
        FCategoriesData.FindByCategoryID(categoryID).Name = newName
        FDatabase.Save()
    End Sub

    ''' <summary>
    ''' Adds the category to the database.
    ''' </summary>
    ''' <param name="categoryID">The category ID.</param>
    ''' <param name="categoryName">Name of the category to add.</param>
    Public Sub AddCategory(ByVal categoryID As Guid, ByVal categoryName As String)
        FCategoriesData.AddCategoriesRow(categoryID, categoryName)
        FDatabase.Save()
    End Sub

    ''' <summary>
    ''' Deletes the given category from the database.
    ''' </summary>
    ''' <param name="categoryID">The ID of the category to remove.</param>
    Public Sub DeleteCategory(ByVal categoryID As Guid)

        ' Remove category from songs
        Dim RowsToDelete As New List(Of Data.SongCategoriesRow)
        For Each Row As Data.SongCategoriesRow In FDatabase.Songs.FCategoriesData
            If Row.CategoryID = categoryID Then RowsToDelete.Add(Row)
        Next
        For Each Row As Data.SongCategoriesRow In RowsToDelete
            Row.Delete()
        Next
        FDatabase.Songs.FCategoriesData.AcceptChanges()

        ' Remove the row from the dataset
        FCategoriesData.RemoveCategoriesRow(FCategoriesData.FindByCategoryID(categoryID))
        FCategoriesData.AcceptChanges()

        ' Save the data
        FDatabase.Save()

    End Sub

    ''' <summary>
    ''' Gets a comma separated list of categories, based on the IDs of each category.
    ''' </summary>
    ''' <param name="categories">The categories whose names to retrieve.</param>
    ''' <returns>The list of category names for each category ID passed in.</returns>
    Public Function GetCommaSeparatedCategoryList(ByVal ParamArray categories() As Guid) As String

        Dim Result As String = String.Empty
        For Each CategoryID As Guid In categories
            Result += Me.GetCategoryName(CategoryID)
            If CategoryID <> categories(categories.Length - 1) Then Result += ", "
        Next
        Return Result

    End Function

    ''' <summary>
    ''' Ensures that a default category exists in the database, and returns its ID.
    ''' A default category is created if necessary.
    ''' </summary>
    ''' <returns>The ID of the default category.</returns>
    Public Function GetOrCreateDefaultCategory() As Guid

        Dim CategoryID As Guid
        If Not CategoryExists(Database.DEFAULT_CATEGORY_NAME) Then
            CategoryID = Guid.NewGuid
            AddCategory(CategoryID, Database.DEFAULT_CATEGORY_NAME)
        Else
            CategoryID = GetCategoryID(Database.DEFAULT_CATEGORY_NAME)
        End If
        Return CategoryID

    End Function

End Class
